package com.lingchen.boot.utils;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * Created by csonezp on 2017/3/1.
 */
public class DateUtil {
    public static String getYesterday() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        return DateFormatUtils.format(cal, "yyyy-MM-dd");
    }

    public static String getToday() {
        Calendar cal = Calendar.getInstance();
        return DateFormatUtils.format(cal, "yyyy-MM-dd");
    }

    public static String getStrDay(Date date, int offset) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, offset);
        return DateFormatUtils.format(cal, "yyyy-MM-dd");
    }
    
    public static int getWeekNumber(Date date) {
    	Calendar cal = Calendar.getInstance();
        cal.setTime(date);
    	return cal.get(Calendar.WEEK_OF_YEAR);
    }
    public static int getYear(Date date) {
    	Calendar cal = Calendar.getInstance();
    	cal.setTime(date);
    	return cal.get(Calendar.YEAR);
    }
    
    public static Date getDay(Date date, int offset) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, offset);
        return cal.getTime();
    }

    public static Date getDayStartTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date getDayEndTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static int getHour(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    public static Date plusHours(Date date, int value) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR_OF_DAY, value);
        return calendar.getTime();
    }

    public static Date getYesterdayDate() {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        return cal.getTime();
    }

    public static int differentDaysByMillisecond(Date start,Date end)
    {
        int days = (int) ((end.getTime() - start.getTime()) / (1000*3600*24));
        return days;
    }
    
    public final static Map<String,List<Object[]>> generateWeekPeriod(String start, String end) throws Exception {
		Date firstMonday = DateUtils.parseDate(start, "yyyy-MM-dd");
		Date lastMonday = DateUtils.parseDate(end, "yyyy-MM-dd");
		return generateWeekPeriod(firstMonday,lastMonday);
	}
    private final static Object[] generateWeek(Date monday) {
    	Calendar c = Calendar.getInstance();
    	c.setTime(monday);
    	return new Object[]{c.get(Calendar.WEEK_OF_YEAR),DateUtil.getStrDay(monday, 0),DateUtil.getStrDay(monday, 6)};
    }
    
    private final static Date addWeekOffset(int weekOffset,Date day) {
    	Calendar c  = Calendar.getInstance();
    	c.setTime(day);
    	c.add(Calendar.DATE, weekOffset*7);
    	return c.getTime();
    }
    public final static Map<String,List<Object[]>> generateWeekPeriod(Date firstMonday, Date lastMonday){
		int weekCount = (int)((lastMonday.getTime()-firstMonday.getTime())/(7*24*3600*1000L));
		System.out.println(weekCount);
		return IntStream.range(0, weekCount+1).mapToObj(i->addWeekOffset(i,firstMonday))
		.collect(Collectors.groupingBy(d->String.valueOf(1900+d.getYear()),Collectors.collectingAndThen(Collectors.toList(), list->{
    					return list.stream().map(d->generateWeek(new Date(d.getTime()))).collect(Collectors.toList());
    				})));
	}

}
